import java.util.Vector;

import TUIO.TuioCursor;
import TUIO.TuioPoint;
import TUIO.TuioProcessing;
import processing.core.*;
    import ddf.minim.analysis.*;
import ddf.minim.effects.BandPass;
import ddf.minim.*;
//import ddf.*;

public class ForwardFFT extends PApplet {
    /**
     * Forward FFT
     * by Damien Di Fede.
     *  
     * This sketch demonstrates how to use an FFT to analyze an AudioBuffer 
     * and draw the resulting spectrum. It also allows you to turn windowing 
     * on and off, but you will see there is not much difference in the spectrum.
     * Press 'w' to turn on windowing, press 'e' to turn it off.
     */
    TuioProcessing tuioClient;
    Minim minim;
    AudioPlayer jingle;
    FFT fft;
    String windowName;
    BandPass bpf;
    int rectX, rectY;   
    int rectSize = 30;
    float maxG;
    boolean rectOver = false;
    private int currentColor;
    public void setup()
    {
       rectX = width-rectSize;
       rectY = 0;
      size(900, 200, P2D);
      minim = new Minim(this);
      
      jingle = minim.loadFile("307-push_-_universal_nation.mp3", 512);
      maxG=jingle.getGain()+41;
      jingle.play();      
      // create an FFT object that has a time-domain buffer the same size as jingle's sample buffer
      // note that this needs to be a power of two and that it means the size of the spectrum
      // will be 512. see the online tutorial for more info.
      fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
      textFont(createFont("SanSerif", 12));
      windowName = "None";
      tuioClient  = new TuioProcessing(this);
    }

    public void draw()
    {
      background(0);
      // perform a forward FFT on the samples in jingle's left buffer
      // note that if jingle were a MONO file, this would be the same as using jingle.right or jingle.left
      
      fft.forward(jingle.mix);
      for(int i = 0; i < fft.specSize(); i++)
      {   
         // for(int a=mouseX; a<mouseX+100;a++){
        //      fft.setBand(a, mouseY);
             // jingle.
           //   fft.setBand(mouseX+1, mouseY);
           //  fft.setBand(mouseX-1, mouseY);
          //    fft.setBand(mouseX+2, mouseY);
           //   fft.setBand(mouseX-2, mouseY);*/
        //  }
       //   fft.setBand(mouseX, mouseY);
          if(height - fft.getBand(i)*10<75){
              int pink = color(255,0,0);
              stroke(pink);
          }else if(75<height - fft.getBand(i)*10&&height - fft.getBand(i)*10<150){
              int pink = color(255,200,100);
              stroke(pink);
          }else if(150<height - fft.getBand(i)*10&&height - fft.getBand(i)*10<190){
              int pink = color(255,250,150);
              stroke(pink);
          }else if(190<height - fft.getBand(i)*10&&height - fft.getBand(i)*10<200){
              int pink = color(0,500,000);
              stroke(pink);
          }else{
              stroke(255);
          }
        // draw the line for frequency band i, scaling it by 4 so we can see it a bit better
        line(i, height, i, height - fft.getBand(i)*4);
      }
      fill(255);
      // keep us informed about the window being used
      text("The window being used is: " + windowName, 5, 20);
   /*   Vector tuioCursorList = tuioClient.getTuioCursors();
      for (int i=0;i<tuioCursorList.size();i++) {
            TuioCursor tcur = (TuioCursor)tuioCursorList.elementAt(i);
            Vector pointList = tcur.getPath();

            if (pointList.size()>0) {
                  stroke(0,0,255);
                  TuioPoint start_point = (TuioPoint)pointList.firstElement();;
                  for (int j=0;j<pointList.size();j++) {
                        TuioPoint end_point = (TuioPoint)pointList.elementAt(j);
                        line(start_point.getScreenX(width),start_point.getScreenY(height),end_point.getScreenX(width),end_point.getScreenY(height));
                        start_point = end_point;
                  }

                  stroke(192,192,192);
                  fill(192,192,192);
                  float cursor_size = 15;
                  float scale_factor = 1;
                  float cur_size = cursor_size*scale_factor; 
                  ellipse( tcur.getScreenX(width), tcur.getScreenY(height),cur_size,cur_size);
                  fill(0);
                  text(""+ tcur.getCursorID(),  tcur.getScreenX(width)-5,  tcur.getScreenY(height)+5);
            }
      }*/

      stroke(200,200,100);
      rect(rectX, rectY, rectSize, 100);
      float y=(jingle.getGain()+35)/41;
      System.out.println(y);
      /*if(y<0){
          y*=-1;
      }*/
      for (int i=100; i>(1-(y))*200;i--){
          line(rectX, i, rectX+rectSize, i);
      }
      if(((jingle.getGain()+21))*100/27>0&&((jingle.getGain()+21))*100/27<100){
          text("The Volume " + ((jingle.getGain()+21))*100/27, 750, 20);
      }else if(((jingle.getGain()+21))*100/27<0){
          text("The Volume 0", 750, 20);
      }else if (((jingle.getGain()+21))*100/27>100){
          text("The Volume 100", 750, 20);
      }
    }
    
    public void mouseDragged(){
      //  bpf = new BandPass(10, 20, jingle.sampleRate());
      //  jingle.addEffect(bpf);
        // map the mouse position to the range [100, 10000], an arbitrary range of passBand frequencies
      //  float passBand = map(mouseX, 0, width, 100, 2000);
      //  bpf.setFreq(passBand);
     //   float bandWidth = map(mouseY, 0, height, 50, 500);
      //  bpf.setBandWidth(bandWidth);
        // prints the new values of the coefficients in the console
      //  bpf.printCoeff();
     // draw the line for frequency band i, scaling it by 4 so we can see it a bit better
        stroke(0);
       // line(rectX, mouseY, rectX+rectSize, mouseY);
        //line(i, height, i, height - fft.getBand(i)*4);
        if(mouseX>rectX&&mouseX<rectX+rectSize){
            
            jingle.pause();
            /*  float y=jingle.getGain();
            if(y<0){
            y*=-1;
            }
            for (int i=200; i>(1-(y/maxG))*200;i--){
            line(rectX, i, rectX+rectSize, i);
    
            }*/
       //   jingle.setGain(((200-mouseY)*(maxG-1)/200));
            if((maxG*(200-mouseY)/200-41)+(maxG-41)>-20&&(maxG*(200-mouseY)/200-41)+(maxG-41)<6){
                jingle.setGain(((maxG*(200-mouseY)/200-41))+6);
            }else if((maxG*(200-mouseY)/200-41)+(maxG-41)<-20){
                jingle.setGain(-41);
            }else if((maxG*(200-mouseY)/200-41)+(maxG-41)<6){
                jingle.setGain(6);
            }
     //     System.out.println(jingle.getGain());
            jingle.play();
        }
    }
    
    public void keyReleased()
    {
      if (key == 'a'){
          fft.window(FFT.NONE);
          windowName="a:"+mouseX;          
         
      }
      if ( key == 'w' ) 
      {
        // a Hamming window can be used to shape the sample buffer that is passed to the FFT
        // this can reduce the amount of noise in the spectrum
        fft.window(FFT.HAMMING);
        windowName = "Hamming";
      }
      
      if ( key == 'e' ) 
      {
        fft.window(FFT.NONE);
        windowName = "None";
      }
    }

    public void stop()
    {
      // always close Minim audio classes when you finish with them
      jingle.close();
      minim.stop();      
      super.stop();
    }

}
